package com.scs.application.core.thread;

import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.utils.BeanValidators;
import com.scs.application.core.utils.SpringUtils;
import com.scs.application.core.utils.StringUtils;

import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @Description: DefaultSaveHandler
 **/
public class DefaultSaveHandler<E> implements BatchSaveHandler<E> {
    private final Validator validator = SpringUtils.getBean(Validator.class);

    private AtomicInteger successCount = new AtomicInteger(0);
    private AtomicInteger failureCount = new AtomicInteger(0);


    private Queue<String> messageList = new ConcurrentLinkedQueue();


    @Override
    public void doValidate(int currentIndex, E entity) {
        BeanValidators.validateWithException(validator, entity);
    }

    @Override
    public void onValidateError(int currentIndex, E entity, ValidationException e) {
        failureCount.incrementAndGet();

        if (e instanceof ConstraintViolationException) {
            messageList.add(MessageFormat.format("第 [{0}] 行数据校验错误：{1}", currentIndex + 2, StringUtils.join(BeanValidators.extractMessage(((ConstraintViolationException) e).getConstraintViolations()))));
        }
    }

    @Override
    public void doSave(int currentIndex, E entity) throws BusinessException {

    }

    @Override
    public void onSaveSuccess(int currentIndex, E entity) {
        successCount.incrementAndGet();
    }

    @Override
    public void onSaveError(int currentIndex, E entity, BusinessException e) {
        failureCount.incrementAndGet();
        messageList.add(e.getMessage());

    }
    public int getSuccessCount() {
        return successCount.intValue();
    }

    public int getFailureCount() {
        return failureCount.intValue();
    }

    public List<String> getMessageList() {
        return Collections.unmodifiableList(messageList.stream().collect(Collectors.toList()));
    }
}


